package com.search.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.base.core.pager.PageBean;
import com.base.core.pager.PageContext;
import com.search.dao.repo.DoctorRepository;
import com.search.entity.Doctor;
import com.search.service.SearchDoctorService;
import com.search.service.dto.SearchDoctor;
import com.search.service.dto.SearchDoctorParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;

import javax.annotation.Resource;

import java.util.List;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.*;

@DubboService(version = "0.0.1-alpha", timeout = 3000, delay = -1)
public class SearchDoctorServiceImpl implements SearchDoctorService {

    @Resource
    private DoctorRepository doctorRepository;


    @Override
    public PageBean<SearchDoctor> search(SearchDoctorParam searchDoctorParam, int page, int size, String sort) {
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        BoolQueryBuilder booleanQueryBuilder = new BoolQueryBuilder();
        if (StringUtils.isNotBlank(searchDoctorParam.getName())) {
            booleanQueryBuilder.must(matchQuery("name", searchDoctorParam.getName()));
        }
        if (StringUtils.isNotBlank(searchDoctorParam.getDepartment())) {
            booleanQueryBuilder.must(matchQuery("department", searchDoctorParam.getDepartment()));
        }
        if (StringUtils.isNotBlank(searchDoctorParam.getJobtitle())) {
            booleanQueryBuilder.must(matchQuery("jobtitle", searchDoctorParam.getJobtitle()));
        }
        if (ObjectUtil.isNotEmpty(searchDoctorParam.getJobtitleId())) {
            booleanQueryBuilder.must(termQuery("jobtitleId", searchDoctorParam.getJobtitleId()));
        }
        if (ObjectUtil.isNotEmpty(searchDoctorParam.getDepartmentId())) {
            booleanQueryBuilder.must(termQuery("departmentId", searchDoctorParam.getDepartmentId()));
        }
        if (ObjectUtil.isNotEmpty(searchDoctorParam.getHospital())) {
            booleanQueryBuilder.must(matchQuery("hospital", searchDoctorParam.getHospital()));
        }
        if (ObjectUtil.isNotEmpty(searchDoctorParam.getCityId())) {
            booleanQueryBuilder.must(termQuery("cityId", searchDoctorParam.getCityId()));
        }
        //排序
        switch (sort.toLowerCase()){
            case "default":
                builder.withSort(SortBuilders.scoreSort().order(SortOrder.DESC));
                break;
            case "service_num":
                builder.withSort(new FieldSortBuilder("serviceNum").unmappedType("Integer").order(SortOrder.DESC));
                break;
            case "rating":
                builder.withSort(new FieldSortBuilder("positiveRating").unmappedType("Integer").order(SortOrder.DESC));
                break;
            case "price":
                builder.withSort(new FieldSortBuilder("minServicePrice").unmappedType("Double").order(SortOrder.ASC));
                break;
        }

        SearchQuery searchQuery = builder
                .withQuery(booleanQueryBuilder)
                .withPageable(PageRequest.of(page-1, size))
                .build();

        Page<Doctor> result = doctorRepository.search(searchQuery);
        List<SearchDoctor> list = result.getContent().stream().map(product -> {
            SearchDoctor searchDoctor = new SearchDoctor();
            searchDoctor.setUserId(product.getUserId());
            searchDoctor.setName(product.getName());
            searchDoctor.setAvatar(product.getAvatar());
            searchDoctor.setBrief(product.getBrief());
            searchDoctor.setCityId(product.getCityId());
            searchDoctor.setMinServicePrice(product.getMinServicePrice());
            searchDoctor.setAvgReponse(product.getAvgReponse());
            searchDoctor.setDepartmentId(product.getDepartmentId());
            searchDoctor.setDepartment(product.getDepartment());
            searchDoctor.setServiceNum(product.getServiceNum());
            searchDoctor.setHospital(product.getHospital());
            return searchDoctor;
        }).collect(Collectors.toList());
        Long count = result.getTotalElements();
        PageContext.setDataCount(count);
        PageContext.setPageSize(new Long(size));
        PageContext.setCurrentPage(new Long(page));
        PageBean<SearchDoctor> searchDoctorPageBean = new PageBean<>(list);
        PageContext.clear();
        return searchDoctorPageBean;
    }
}
